/*
 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.lang.reflect;

import sun.reflect.CallerSensitive;
import sun.reflect.FieldAccessor;
import sun.reflect.Reflection;
import sun.reflect.generics.repository.FieldRepository;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.scope.ClassScope;
import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.Objects;
import sun.reflect.annotation.AnnotationParser;
import sun.reflect.annotation.AnnotationSupport;
import sun.reflect.annotation.TypeAnnotation;
import sun.reflect.annotation.TypeAnnotationParser;

/**
 * {@code Field} 提供关于类或接口的单个字段的信息，并提供对该字段的动态访问。
 * 反射的字段可以是类（静态）字段或实例字段。
 *
 * <p>{@code Field} 允许在 get 或 set 访问操作期间发生扩展转换，
 * 但如果发生收缩转换，则抛出 {@code IllegalArgumentException}。
 *
 * @see Member
 * @see java.lang.Class
 * @see java.lang.Class#getFields()
 * @see java.lang.Class#getField(String)
 * @see java.lang.Class#getDeclaredFields()
 * @see java.lang.Class#getDeclaredField(String)
 *
 * @author Kenneth Russell
 * @author Nakul Saraiya
 */
public final
class Field extends AccessibleObject implements Member {

    private Class<?>            clazz;
    private int                 slot;
    // This is guaranteed to be interned by the VM in the 1.4
    // reflection implementation
    private String              name;
    private Class<?>            type;
    private int                 modifiers;
    // Generics and annotations support
    private transient String    signature;
    // generic info repository; lazily initialized
    private transient FieldRepository genericInfo;
    private byte[]              annotations;
    // Cached field accessor created without override
    private FieldAccessor fieldAccessor;
    // Cached field accessor created with override
    private FieldAccessor overrideFieldAccessor;
    // For sharing of FieldAccessors. This branching structure is
    // currently only two levels deep (i.e., one root Field and
    // potentially many Field objects pointing to it.)
    //
    // If this branching structure would ever contain cycles, deadlocks can
    // occur in annotation code.
    private Field               root;

    // Generics infrastructure

    private String getGenericSignature() {return signature;}

    // Accessor for factory
    private GenericsFactory getFactory() {
        Class<?> c = getDeclaringClass();
        // create scope and factory
        return CoreReflectionFactory.make(c, ClassScope.make(c));
    }

    // Accessor for generic info repository
    private FieldRepository getGenericInfo() {
        // lazily initialize repository if necessary
        if (genericInfo == null) {
            // create and cache generic info repository
            genericInfo = FieldRepository.make(getGenericSignature(),
                                               getFactory());
        }
        return genericInfo; //return cached repository
    }


    /**
     * 包私有构造器，由 ReflectAccess 使用，通过 sun.reflect.LangReflectAccess
     * 在 java.lang 包的 Java 代码中启用这些对象的实例化。
     */
    Field(Class<?> declaringClass,
          String name,
          Class<?> type,
          int modifiers,
          int slot,
          String signature,
          byte[] annotations)
    {
        this.clazz = declaringClass;
        this.name = name;
        this.type = type;
        this.modifiers = modifiers;
        this.slot = slot;
        this.signature = signature;
        this.annotations = annotations;
    }

    /**
     * 包私有例程（通过 ReflectAccess 暴露给 java.lang.Class），
     * 返回此 Field 的副本。副本的 "root" 字段指向此 Field。
     */
    Field copy() {
        // This routine enables sharing of FieldAccessor objects
        // among Field objects which refer to the same underlying
        // method in the VM. (All of this contortion is only necessary
        // because of the "accessibility" bit in AccessibleObject,
        // which implicitly requires that new java.lang.reflect
        // objects be fabricated for each reflective call on Class
        // objects.)
        if (this.root != null)
            throw new IllegalArgumentException("Can not copy a non-root Field");

        Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations);
        res.root = this;
        // Might as well eagerly propagate this if already present
        res.fieldAccessor = fieldAccessor;
        res.overrideFieldAccessor = overrideFieldAccessor;

        return res;
    }

    /**
     * 返回表示声明此 {@code Field} 对象所表示字段的类或接口的 {@code Class} 对象。
     */
    public Class<?> getDeclaringClass() {
        return clazz;
    }

    /**
     * 返回此 {@code Field} 对象所表示字段的名称。
     */
    public String getName() {
        return name;
    }

    /**
     * 以整数形式返回此 {@code Field} 对象所表示字段的 Java 语言修饰符。
     * 应使用 {@code Modifier} 类来解码修饰符。
     *
     * @see Modifier
     */
    public int getModifiers() {
        return modifiers;
    }

    /**
     * 如果此字段表示枚举类型的元素，则返回 {@code true}；否则返回 {@code false}。
     *
     * @return 当且仅当此字段表示枚举类型的元素时返回 {@code true}。
     * @since 1.5
     */
    public boolean isEnumConstant() {
        return (getModifiers() & Modifier.ENUM) != 0;
    }

    /**
     * 如果此字段是合成字段，则返回 {@code true}；否则返回 {@code false}。
     *
     * @return 当且仅当此字段是 Java 语言规范定义的合成字段时返回 true。
     * @since 1.5
     */
    public boolean isSynthetic() {
        return Modifier.isSynthetic(getModifiers());
    }

    /**
     * 返回标识此 {@code Field} 对象所表示字段的声明类型的 {@code Class} 对象。
     *
     * @return 标识此对象所表示字段的声明类型的 {@code Class} 对象
     */
    public Class<?> getType() {
        return type;
    }

    /**
     * 返回表示此 {@code Field} 对象所表示字段的声明类型的 {@code Type} 对象。
     *
     * <p>如果 {@code Type} 是参数化类型，返回的 {@code Type} 对象必须准确反映
     * 源代码中使用的实际类型参数。
     *
     * <p>如果底层字段的类型是类型变量或参数化类型，则创建它。否则，解析它。
     *
     * @return 表示此 {@code Field} 对象所表示字段的声明类型的 {@code Type} 对象
     * @throws GenericSignatureFormatError 如果泛型字段签名不符合
     *     <cite>Java&trade; 虚拟机规范</cite>中指定的格式
     * @throws TypeNotPresentException 如果底层字段的泛型类型签名
     *     引用不存在的类型声明
     * @throws MalformedParameterizedTypeException 如果底层字段的泛型签名
     *     引用由于任何原因无法实例化的参数化类型
     * @since 1.5
     */
    public Type getGenericType() {
        if (getGenericSignature() != null)
            return getGenericInfo().getGenericType();
        else
            return getType();
    }


    /**
     * 将此 {@code Field} 与指定对象进行比较。如果对象相同则返回 true。
     * 如果两个 {@code Field} 对象由同一个类声明并且具有相同的名称和类型，
     * 则它们是相同的。
     */
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof Field) {
            Field other = (Field)obj;
            return (getDeclaringClass() == other.getDeclaringClass())
                && (getName() == other.getName())
                && (getType() == other.getType());
        }
        return false;
    }

    /**
     * 返回此 {@code Field} 的哈希码。这是通过底层字段的声明类名称
     * 和其名称的哈希码的异或运算计算得出的。
     */
    public int hashCode() {
        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
    }

    /**
     * 返回描述此 {@code Field} 的字符串。格式是字段的访问修饰符（如果有），
     * 后跟字段类型，后跟一个空格，后跟声明字段的类的完全限定名，
     * 后跟一个句点，后跟字段的名称。
     * 例如：
     * <pre>
     *    public static final int java.lang.Thread.MIN_PRIORITY
     *    private int java.io.FileDescriptor.fd
     * </pre>
     *
     * <p>修饰符按照"Java 语言规范"指定的规范顺序放置。
     * 首先是 {@code public}、{@code protected} 或 {@code private}，
     * 然后是其他修饰符，顺序如下：{@code static}、{@code final}、
     * {@code transient}、{@code volatile}。
     *
     * @return 描述此 {@code Field} 的字符串
     * @jls 8.3.1 Field Modifiers
     */
    public String toString() {
        int mod = getModifiers();
        return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
            + getType().getTypeName() + " "
            + getDeclaringClass().getTypeName() + "."
            + getName());
    }

    /**
     * 返回描述此 {@code Field} 的字符串，包括其泛型类型。
     * 格式是字段的访问修饰符（如果有），后跟泛型字段类型，后跟一个空格，
     * 后跟声明字段的类的完全限定名，后跟一个句点，后跟字段的名称。
     *
     * <p>修饰符按照"Java 语言规范"指定的规范顺序放置。
     * 首先是 {@code public}、{@code protected} 或 {@code private}，
     * 然后是其他修饰符，顺序如下：{@code static}、{@code final}、
     * {@code transient}、{@code volatile}。
     *
     * @return 描述此 {@code Field} 的字符串，包括其泛型类型
     *
     * @since 1.5
     * @jls 8.3.1 Field Modifiers
     */
    public String toGenericString() {
        int mod = getModifiers();
        Type fieldType = getGenericType();
        return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
            + fieldType.getTypeName() + " "
            + getDeclaringClass().getTypeName() + "."
            + getName());
    }

    /**
     * 返回此 {@code Field} 在指定对象上所表示字段的值。
     * 如果值具有基本类型，则自动包装在对象中。
     *
     * <p>底层字段的值按如下方式获取：
     *
     * <p>如果底层字段是静态字段，则忽略 {@code obj} 参数；它可以为 null。
     *
     * <p>否则，底层字段是实例字段。如果指定的 {@code obj} 参数为 null，
     * 该方法抛出 {@code NullPointerException}。如果指定的对象不是
     * 声明底层字段的类或接口的实例，该方法抛出 {@code IllegalArgumentException}。
     *
     * <p>如果此 {@code Field} 对象正在强制执行 Java 语言访问控制，
     * 并且底层字段不可访问，该方法抛出 {@code IllegalAccessException}。
     * 如果底层字段是静态的，声明该字段的类如果尚未初始化则进行初始化。
     *
     * <p>否则，从底层实例或静态字段检索值。如果字段具有基本类型，
     * 则在返回之前将值包装在对象中，否则按原样返回。
     *
     * <p>如果字段在 {@code obj} 的类型中被隐藏，
     * 则根据前述规则获取字段的值。
     *
     * @param obj 要从中提取所表示字段值的对象
     * @return 对象 {@code obj} 中所表示字段的值；
     * 基本值在返回之前包装在适当的对象中
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者）。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     */
    @CallerSensitive
    public Object get(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).get(obj);
    }

    /**
     * 获取静态或实例 {@code boolean} 字段的值。
     *
     * @param obj 要从中提取 {@code boolean} 值的对象
     * @return {@code boolean} 字段的值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code boolean} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#get
     */
    @CallerSensitive
    public boolean getBoolean(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getBoolean(obj);
    }

    /**
     * 获取静态或实例 {@code byte} 字段的值。
     *
     * @param obj 要从中提取 {@code byte} 值的对象
     * @return {@code byte} 字段的值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code byte} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#get
     */
    @CallerSensitive
    public byte getByte(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getByte(obj);
    }

    /**
     * 获取 {@code char} 类型或通过扩展转换可转换为 {@code char} 类型的
     * 其他基本类型的静态或实例字段的值。
     *
     * @param obj 要从中提取 {@code char} 值的对象
     * @return 转换为 {@code char} 类型的字段值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code char} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see Field#get
     */
    @CallerSensitive
    public char getChar(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getChar(obj);
    }

    /**
     * 获取 {@code short} 类型或通过扩展转换可转换为 {@code short} 类型的
     * 其他基本类型的静态或实例字段的值。
     *
     * @param obj 要从中提取 {@code short} 值的对象
     * @return 转换为 {@code short} 类型的字段值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code short} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#get
     */
    @CallerSensitive
    public short getShort(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getShort(obj);
    }

    /**
     * 获取 {@code int} 类型或通过扩展转换可转换为 {@code int} 类型的
     * 其他基本类型的静态或实例字段的值。
     *
     * @param obj 要从中提取 {@code int} 值的对象
     * @return 转换为 {@code int} 类型的字段值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code int} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#get
     */
    @CallerSensitive
    public int getInt(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getInt(obj);
    }

    /**
     * 获取 {@code long} 类型或通过扩展转换可转换为 {@code long} 类型的
     * 其他基本类型的静态或实例字段的值。
     *
     * @param obj 要从中提取 {@code long} 值的对象
     * @return 转换为 {@code long} 类型的字段值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code long} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#get
     */
    @CallerSensitive
    public long getLong(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getLong(obj);
    }

    /**
     * 获取 {@code float} 类型或通过扩展转换可转换为 {@code float} 类型的
     * 其他基本类型的静态或实例字段的值。
     *
     * @param obj 要从中提取 {@code float} 值的对象
     * @return 转换为 {@code float} 类型的字段值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code float} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see Field#get
     */
    @CallerSensitive
    public float getFloat(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getFloat(obj);
    }

    /**
     * 获取 {@code double} 类型或通过扩展转换可转换为 {@code double} 类型的
     * 其他基本类型的静态或实例字段的值。
     *
     * @param obj 要从中提取 {@code double} 值的对象
     * @return 转换为 {@code double} 类型的字段值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果字段值无法通过扩展转换转换为 {@code double} 类型。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#get
     */
    @CallerSensitive
    public double getDouble(Object obj)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        return getFieldAccessor(obj).getDouble(obj);
    }

    /**
     * 将此 {@code Field} 对象在指定对象参数上所表示的字段设置为指定的新值。
     * 如果底层字段具有基本类型，新值会自动拆箱。
     *
     * <p>操作按如下方式进行：
     *
     * <p>如果底层字段是静态的，则忽略 {@code obj} 参数；它可以为 null。
     *
     * <p>否则底层字段是实例字段。如果指定的对象参数为 null，
     * 该方法抛出 {@code NullPointerException}。如果指定的对象参数不是
     * 声明底层字段的类或接口的实例，该方法抛出 {@code IllegalArgumentException}。
     *
     * <p>如果此 {@code Field} 对象正在强制执行 Java 语言访问控制，
     * 并且底层字段不可访问，该方法抛出 {@code IllegalAccessException}。
     *
     * <p>如果底层字段是 final 的，该方法抛出 {@code IllegalAccessException}，
     * 除非对此 {@code Field} 对象成功调用了 {@code setAccessible(true)}
     * 并且字段是非静态的。以这种方式设置 final 字段只有在反序列化或
     * 重构具有空白 final 字段的类的实例期间才有意义，在它们被程序的其他部分
     * 访问之前。在任何其他上下文中使用可能会产生不可预测的效果，
     * 包括程序的其他部分继续使用此字段的原始值的情况。
     *
     * <p>如果底层字段是基本类型，则尝试拆箱转换以将新值转换为基本类型的值。
     * 如果此尝试失败，该方法抛出 {@code IllegalArgumentException}。
     *
     * <p>如果在可能的拆箱之后，新值无法通过恒等或扩展转换转换为底层字段的类型，
     * 该方法抛出 {@code IllegalArgumentException}。
     *
     * <p>如果底层字段是静态的，声明该字段的类如果尚未初始化则进行初始化。
     *
     * <p>字段被设置为可能拆箱和扩展的新值。
     *
     * <p>如果字段在 {@code obj} 的类型中被隐藏，
     * 则根据前述规则设置字段的值。
     *
     * @param obj 应修改其字段的对象
     * @param value 正在修改的 {@code obj} 字段的新值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问或为 final。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果拆箱转换失败。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     */
    @CallerSensitive
    public void set(Object obj, Object value)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).set(obj, value);
    }

    /**
     * Sets the value of a field as a {@code boolean} on the specified object.
     * This method is equivalent to
     * {@code set(obj, zObj)},
     * where {@code zObj} is a {@code Boolean} object and
     * {@code zObj.booleanValue() == z}.
     *
     * @param obj the object whose field should be modified
     * @param z   the new value for the field of {@code obj}
     * being modified
     *
     * @exception IllegalAccessException    if this {@code Field} object
     *              is enforcing Java language access control and the underlying
     *              field is either inaccessible or final.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof),
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    @CallerSensitive
    public void setBoolean(Object obj, boolean z)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setBoolean(obj, z);
    }

    /**
     * Sets the value of a field as a {@code byte} on the specified object.
     * This method is equivalent to
     * {@code set(obj, bObj)},
     * where {@code bObj} is a {@code Byte} object and
     * {@code bObj.byteValue() == b}.
     *
     * @param obj the object whose field should be modified
     * @param b   the new value for the field of {@code obj}
     * being modified
     *
     * @exception IllegalAccessException    if this {@code Field} object
     *              is enforcing Java language access control and the underlying
     *              field is either inaccessible or final.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof),
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    @CallerSensitive
    public void setByte(Object obj, byte b)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setByte(obj, b);
    }

    /**
     * Sets the value of a field as a {@code char} on the specified object.
     * This method is equivalent to
     * {@code set(obj, cObj)},
     * where {@code cObj} is a {@code Character} object and
     * {@code cObj.charValue() == c}.
     *
     * @param obj the object whose field should be modified
     * @param c   the new value for the field of {@code obj}
     * being modified
     *
     * @exception IllegalAccessException    if this {@code Field} object
     *              is enforcing Java language access control and the underlying
     *              field is either inaccessible or final.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof),
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    @CallerSensitive
    public void setChar(Object obj, char c)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setChar(obj, c);
    }

    /**
     * Sets the value of a field as a {@code short} on the specified object.
     * This method is equivalent to
     * {@code set(obj, sObj)},
     * where {@code sObj} is a {@code Short} object and
     * {@code sObj.shortValue() == s}.
     *
     * @param obj the object whose field should be modified
     * @param s   the new value for the field of {@code obj}
     * being modified
     *
     * @exception IllegalAccessException    if this {@code Field} object
     *              is enforcing Java language access control and the underlying
     *              field is either inaccessible or final.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof),
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    @CallerSensitive
    public void setShort(Object obj, short s)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setShort(obj, s);
    }

    /**
     * Sets the value of a field as an {@code int} on the specified object.
     * This method is equivalent to
     * {@code set(obj, iObj)},
     * where {@code iObj} is a {@code Integer} object and
     * {@code iObj.intValue() == i}.
     *
     * @param obj the object whose field should be modified
     * @param i   the new value for the field of {@code obj}
     * being modified
     *
     * @exception IllegalAccessException    if this {@code Field} object
     *              is enforcing Java language access control and the underlying
     *              field is either inaccessible or final.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof),
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    @CallerSensitive
    public void setInt(Object obj, int i)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setInt(obj, i);
    }

    /**
     * Sets the value of a field as a {@code long} on the specified object.
     * This method is equivalent to
     * {@code set(obj, lObj)},
     * where {@code lObj} is a {@code Long} object and
     * {@code lObj.longValue() == l}.
     *
     * @param obj the object whose field should be modified
     * @param l   the new value for the field of {@code obj}
     * being modified
     *
     * @exception IllegalAccessException    if this {@code Field} object
     *              is enforcing Java language access control and the underlying
     *              field is either inaccessible or final.
     * @exception IllegalArgumentException  if the specified object is not an
     *              instance of the class or interface declaring the underlying
     *              field (or a subclass or implementor thereof),
     *              or if an unwrapping conversion fails.
     * @exception NullPointerException      if the specified object is null
     *              and the field is an instance field.
     * @exception ExceptionInInitializerError if the initialization provoked
     *              by this method fails.
     * @see       Field#set
     */
    @CallerSensitive
    public void setLong(Object obj, long l)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setLong(obj, l);
    }

    /**
     * 在指定对象上将字段的值设置为 {@code float}。
     * 此方法等价于 {@code set(obj, fObj)}，
     * 其中 {@code fObj} 是 {@code Float} 对象且
     * {@code fObj.floatValue() == f}。
     *
     * @param obj 应修改其字段的对象
     * @param f   正在修改的 {@code obj} 字段的新值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问或为 final。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果拆箱转换失败。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#set
     */
    @CallerSensitive
    public void setFloat(Object obj, float f)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setFloat(obj, f);
    }

    /**
     * 在指定对象上将字段的值设置为 {@code double}。
     * 此方法等价于 {@code set(obj, dObj)}，
     * 其中 {@code dObj} 是 {@code Double} 对象且
     * {@code dObj.doubleValue() == d}。
     *
     * @param obj 应修改其字段的对象
     * @param d   正在修改的 {@code obj} 字段的新值
     *
     * @exception IllegalAccessException    如果此 {@code Field} 对象
     *              正在强制执行 Java 语言访问控制并且底层字段不可访问或为 final。
     * @exception IllegalArgumentException  如果指定的对象不是
     *              声明底层字段的类或接口的实例（或其子类或实现者），
     *              或者如果拆箱转换失败。
     * @exception NullPointerException      如果指定的对象为 null
     *              并且字段是实例字段。
     * @exception ExceptionInInitializerError 如果此方法引发的初始化失败。
     * @see       Field#set
     */
    @CallerSensitive
    public void setDouble(Object obj, double d)
        throws IllegalArgumentException, IllegalAccessException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        getFieldAccessor(obj).setDouble(obj, d);
    }

    // security check is done before calling this method
    private FieldAccessor getFieldAccessor(Object obj)
        throws IllegalAccessException
    {
        boolean ov = override;
        FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor;
        return (a != null) ? a : acquireFieldAccessor(ov);
    }

    // NOTE that there is no synchronization used here. It is correct
    // (though not efficient) to generate more than one FieldAccessor
    // for a given Field. However, avoiding synchronization will
    // probably make the implementation more scalable.
    private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) {
        // First check to see if one has been created yet, and take it
        // if so
        FieldAccessor tmp = null;
        if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck);
        if (tmp != null) {
            if (overrideFinalCheck)
                overrideFieldAccessor = tmp;
            else
                fieldAccessor = tmp;
        } else {
            // Otherwise fabricate one and propagate it up to the root
            tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck);
            setFieldAccessor(tmp, overrideFinalCheck);
        }

        return tmp;
    }

    // Returns FieldAccessor for this Field object, not looking up
    // the chain to the root
    private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) {
        return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor;
    }

    // Sets the FieldAccessor for this Field object and
    // (recursively) its root
    private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) {
        if (overrideFinalCheck)
            overrideFieldAccessor = accessor;
        else
            fieldAccessor = accessor;
        // Propagate up
        if (root != null) {
            root.setFieldAccessor(accessor, overrideFinalCheck);
        }
    }

    /**
     * @throws NullPointerException {@inheritDoc}
     * @since 1.5
     */
    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
        Objects.requireNonNull(annotationClass);
        return annotationClass.cast(declaredAnnotations().get(annotationClass));
    }

    /**
     * {@inheritDoc}
     * @throws NullPointerException {@inheritDoc}
     * @since 1.8
     */
    @Override
    public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
        Objects.requireNonNull(annotationClass);

        return AnnotationSupport.getDirectlyAndIndirectlyPresent(declaredAnnotations(), annotationClass);
    }

    /**
     * {@inheritDoc}
     */
    public Annotation[] getDeclaredAnnotations()  {
        return AnnotationParser.toArray(declaredAnnotations());
    }

    private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;

    private synchronized  Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
        if (declaredAnnotations == null) {
            Field root = this.root;
            if (root != null) {
                declaredAnnotations = root.declaredAnnotations();
            } else {
                declaredAnnotations = AnnotationParser.parseAnnotations(
                        annotations,
                        sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
                        getDeclaringClass());
            }
        }
        return declaredAnnotations;
    }

    private native byte[] getTypeAnnotationBytes0();

    /**
     * 返回一个 AnnotatedType 对象，该对象表示使用类型来指定
     * 此 Field 所表示字段的声明类型。
     * @return 表示此 Field 所表示字段的声明类型的对象
     *
     * @since 1.8
     */
    public AnnotatedType getAnnotatedType() {
        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
                                                       sun.misc.SharedSecrets.getJavaLangAccess().
                                                           getConstantPool(getDeclaringClass()),
                                                       this,
                                                       getDeclaringClass(),
                                                       getGenericType(),
                                                       TypeAnnotation.TypeAnnotationTarget.FIELD);
}
}
